2 位追蹤者

效能調校

有許多因素會影響您的 Web 應用程式效能。有些是環境因素,有些與您的程式碼有關,而另一些則與 Yii 本身有關。在本節中,我們將列舉大多數這些因素,並說明如何透過調整這些因素來改善您的應用程式效能。

最佳化您的 PHP 環境

良好設定的 PHP 環境非常重要。為了獲得最佳效能,

  • 使用最新的穩定 PHP 版本。PHP 的主要版本發布可能會帶來顯著的效能提升。
  • 使用 Opcache (PHP 5.5 或更新版本) 或 APC (PHP 5.4) 啟用位元組碼快取。位元組碼快取避免了每次傳入請求時花費在解析和包含 PHP 腳本的時間。
  • 調整 realpath() 快取.

停用偵錯模式

在生產環境中執行應用程式時,您應停用偵錯模式。Yii 使用名為 YII_DEBUG 的常數值來指示是否應啟用偵錯模式。啟用偵錯模式後,Yii 將花費額外時間來產生和記錄偵錯資訊。

您可以將以下程式碼行放在 進入點腳本 的開頭以停用偵錯模式

defined('YII_DEBUG') or define('YII_DEBUG', false);

資訊:YII_DEBUG 的預設值為 false。因此,如果您確定您沒有在應用程式程式碼的其他地方變更其預設值,您可以直接移除上述程式碼行以停用偵錯模式。

使用快取技術

您可以使用各種快取技術來顯著改善應用程式的效能。例如,如果您的應用程式允許使用者以 Markdown 格式輸入文字,您可以考慮快取已解析的 Markdown 內容,以避免在每次請求中重複解析相同的 Markdown 文字。請參閱 快取 章節,以了解 Yii 提供的快取支援。

啟用結構描述快取

結構描述快取是一種特殊的快取功能,當您使用 Active Record 時,應始終啟用它。如您所知,Active Record 非常聰明,可以偵測 DB 表格的結構描述資訊 (例如,欄位名稱、欄位類型、約束),而無需您手動描述它們。Active Record 透過執行額外的 SQL 查詢來取得此資訊。透過啟用結構描述快取,檢索到的結構描述資訊將儲存在快取中,並在未來的請求中重複使用。

若要啟用結構描述快取,請設定一個 cache 應用程式組件 以儲存結構描述資訊,並在 yii\db\Connection::$enableSchemaCache 中將 應用程式組態 設定為 true

return [
    // ...
    'components' => [
        // ...
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase',
            'username' => 'root',
            'password' => '',
            'enableSchemaCache' => true,

            // Duration of schema cache.
            'schemaCacheDuration' => 3600,

            // Name of the cache component used to store schema information
            'schemaCache' => 'cache',
        ],
    ],
];

合併與最小化資源

複雜的 Web 頁面通常包含許多 CSS 和/或 JavaScript 資源檔案。為了減少 HTTP 請求的數量和這些資源的整體下載大小,您應考慮將它們合併為單個檔案並壓縮它。這可以大大縮短頁面載入時間並降低伺服器負載。有關更多詳細資訊,請參閱 資源 章節。

最佳化 Session 儲存

預設情況下,Session 資料儲存在檔案中。實作方式是從開啟 Session 到透過 session_write_close() (在 Yii 中可以透過 Yii::$app->session->close() 完成) 或在請求結束時關閉 Session 檔案的過程中鎖定檔案。當 Session 檔案被鎖定時,所有其他嘗試使用相同 Session 的請求都會被封鎖,即等待初始請求釋放 Session 檔案。這對於開發和可能的小型專案來說沒問題。但是,當涉及到處理大量並發請求時,最好使用更複雜的儲存方式,例如資料庫。Yii 開箱即用地支援各種 Session 儲存方式。您可以透過在 應用程式組態 中設定 session 組件來使用這些儲存方式,如下所示,

return [
    // ...
    'components' => [
        'session' => [
            'class' => 'yii\web\DbSession',

            // Set the following if you want to use DB component other than
            // default 'db'.
            // 'db' => 'mydb',

            // To override default session table, set the following
            // 'sessionTable' => 'my_session',
        ],
    ],
];

上述組態使用資料庫表格來儲存 Session 資料。預設情況下,它將使用 db 應用程式組件作為資料庫連線,並將 Session 資料儲存在 session 表格中。不過,您必須事先建立 session 表格,如下所示,

CREATE TABLE session (
    id CHAR(40) NOT NULL PRIMARY KEY,
    expire INTEGER,
    data BLOB
)

您也可以透過使用 yii\web\CacheSession 將 Session 資料儲存在快取中。理論上,您可以使用任何支援的 快取儲存方式。但是請注意,某些快取儲存方式可能會在達到儲存限制時清除快取資料。因此,您應主要使用那些不強制執行儲存限制的快取儲存方式。

如果您的伺服器上有 Redis,強烈建議您使用 yii\redis\Session 將其用作 Session 儲存方式。

最佳化資料庫

執行資料庫查詢和從資料庫提取資料通常是 Web 應用程式中的主要效能瓶頸。雖然使用 資料快取 技術可以減輕效能衝擊,但它並不能完全解決問題。當資料庫包含大量資料且快取資料無效時,在沒有適當的資料庫和查詢設計的情況下,提取最新資料可能會非常昂貴。

改善資料庫查詢效能的通用技術是為需要依據篩選的表格欄位建立索引。例如,如果您需要依據 username 尋找使用者記錄,則應在 username 上建立索引。請注意,雖然索引可以使 SELECT 查詢快得多,但它會減慢 INSERT、UPDATE 和 DELETE 查詢的速度。

對於複雜的資料庫查詢,建議您建立資料庫視圖以節省查詢解析和準備時間。

最後但並非最不重要的一點是,在您的 SELECT 查詢中使用 LIMIT。這避免了從資料庫提取大量資料並耗盡分配給 PHP 的記憶體。

使用純陣列

雖然 Active Record 非常方便使用,但當您需要從資料庫檢索大量資料時,它不如使用純陣列有效率。在這種情況下,您可以考慮在使用 Active Record 查詢資料時呼叫 asArray(),以便檢索到的資料表示為陣列而不是笨重的 Active Record 物件。例如,

class PostController extends Controller
{
    public function actionIndex()
    {
        $posts = Post::find()->limit(100)->asArray()->all();
        
        return $this->render('index', ['posts' => $posts]);
    }
}

在上面的程式碼中,$posts 將被填充為表格列的陣列。每一列都是一個純陣列。若要存取第 i 列的 title 欄位,您可以使用運算式 $posts[$i]['title']

您也可以使用 DAO 來建構查詢並以純陣列檢索資料。

最佳化 Composer 自動載入器

由於 Composer 自動載入器用於包含大多數第三方類別檔案,因此您應考慮透過執行以下命令來最佳化它

composer dumpautoload -o

此外,您可以考慮使用 權威類別映射APCu 快取。請注意,這兩種最佳化可能適用於您的特定情況,也可能不適用。

離線處理資料

當請求涉及某些資源密集型操作時,您應考慮以離線模式執行這些操作的方式,而無需使用者等待它們完成。

有兩種離線處理資料的方法:拉取和推送。

在拉取方法中,每當請求涉及某些複雜操作時,您都會建立一個任務並將其儲存在持久性儲存空間中,例如資料庫。然後,您使用單獨的進程 (例如 cron 工作) 來拉取任務並處理它們。此方法易於實作,但它有一些缺點。例如,任務進程需要定期從任務儲存空間拉取。如果拉取頻率太低,則任務可能會延遲很長時間才被處理,但如果頻率太高,則會引入很高的開銷。

在推送方法中,您將使用消息佇列 (例如 RabbitMQ、ActiveMQ、Amazon SQS 等) 來管理任務。每當將新任務放入佇列時,它將啟動或通知任務處理進程以觸發任務處理。

效能分析

您應分析您的程式碼以找出效能瓶頸,並採取適當的措施。以下分析工具可能很有用

準備應用程式以進行擴展

當任何方法都無法幫助您時,您可以嘗試使您的應用程式具有可擴展性。在 Configuring a Yii 2 Application for an Autoscaling Stack 中提供了良好的介紹。

發現錯字或您認為此頁面需要改進嗎?
在 github 上編輯它 !